﻿Imports Clo = Enhancements.Core.Logging
Imports Ere = Enhancements.Basic.RegularExpressions
Imports Exe = Enhancements.Basic.Expressions
Imports Gen = System.Collections.Generic
Imports Glo = System.Globalization
Imports Iou = System.IO
Imports Ref = System.Reflection
Imports Reg = System.Text.RegularExpressions
Imports Sys = System
Imports Tex = System.Text
Imports Val = Enhancements.Basic.Expressions.Values
Imports Xsd = System.Xml.Schema
Imports W3c = System.Xml

Namespace Enhancements.Basic.Expressions.Functions
    ''' <summary>Represents a function signature specification.</summary>
    <Serializable(), DebuggerStepThrough()> _
    Public NotInheritable Class FunctionSignature

        ''' <summary>Initializes a FunctionSignature instance with the specified parameters and result specifications.</summary>
        ''' <param name="_parameters">Parameters specification.</param>
        ''' <param name="_result">Result specification.</param>
        ''' <exception cref="FunctionSignatureParametersAreValidNotException">_parameters are invalid.</exception>
        ''' <exception cref="FunctionSignatureResultIsValidNotException">_result is invalid.</exception>
        Public Sub New(ByVal _parameters() As FunctionSignatureParameter, ByVal _result As FunctionSignatureResult)
            Parameters = _parameters
            Result = _result
        End Sub

        Private __Parameters() As FunctionSignatureParameter = {}
        ''' <summary>Gets the parameters specified.</summary>
        Public Property Parameters() As FunctionSignatureParameter()
            Get
                Return __Parameters
            End Get
            Private Set(ByVal _value() As FunctionSignatureParameter)
                Try
                    _value.IsNullNot("Parameters._value", True)
                    _value.IsListFilled("Parameters._value", True)
                    ___Identifiers.AssertAreValidAndRepeatedNot((From _valueOne As FunctionSignatureParameter In _value Select _valueOne.Name).ToArray(), True)
                Catch _exception As Sys.Exception
                    FunctionSignatureParametersAreValidNotException.___Throw(_value, _exception)
                End Try

                __Parameters = _value
            End Set
        End Property

        Private __Result As FunctionSignatureResult = Nothing
        ''' <summary>Gets the result specified.</summary>
        Public Property Result() As FunctionSignatureResult
            Get
                Return __Result
            End Get
            Private Set(ByVal _value As FunctionSignatureResult)
                Try
                    _value.IsNullNot("Result._value", True)
                Catch _exception As Sys.Exception
                    FunctionSignatureResultIsValidNotException.___Throw(_value, _exception)
                End Try

                __Result = _value
            End Set
        End Property

        ''' <summary>Compares two function signatures for equalty.</summary>
        ''' <remarks>Two function signatures are considered equal if both have the same parameters count and if all the parameters types are the same when considering both signatures from left to right.</remarks>
        ''' <param name="_secondObject">Second function signature to evaluate.</param>
        ''' <returns> </returns>
        Public Overrides Function Equals(ByVal _secondObject As Sys.Object) As System.Boolean
            Dim _returnValue As System.Boolean = False
            If Assert.IsNullNot(_secondObject, "_secondObject", False) Then
                If Assert.IsOfType(_secondObject, "_secondObject", GetType(FunctionSignature), False) Then
                    Dim _secondFunctionSignature As FunctionSignature = CType(_secondObject, FunctionSignature)
                    If Me.Parameters.Count = _secondFunctionSignature.Parameters.Count Then
                        If Me.Parameters.Count = 0 Then
                            _returnValue = True
                        Else
                            _returnValue = True
                            For _counter As Sys.Int32 = 0 To Me.Parameters.Count - 1
                                If Me.Parameters(_counter).Type.IsNot("Me.Parameters(_counter).Type", _secondFunctionSignature.Parameters(_counter).Type, "_secondFunctionSignature.Parameters(_counter).Type", False) Then
                                    _returnValue = False
                                    Exit For
                                End If
                            Next _counter
                        End If
                    End If
                End If
            End If

            Return _returnValue
        End Function

        Friend Shared Function ___IsCompatibleWithParameters(ByVal _functionSignature As FunctionSignature, ByVal ParamArray _parameters() As Token) As System.Boolean
            Dim _returnValue As System.Boolean = False
            If _functionSignature.IsNullNot("_functionSignature", False) Then
                If _parameters.IsNullNot("_parameters", False) Then
                    If _parameters.IsListFilled("_parameters", False) Then
                        If _functionSignature.Parameters.Length.IsInRange("_functionSignature.Parameters.Length", _parameters.Length, _parameters.Length, False) Then
                            _returnValue = True
                            For _counter As Sys.Int32 = 0 To _functionSignature.Parameters.Length - 1
                                If _parameters(_counter).GetType().IsDerivedOf("_parameters(_counter).GetType()", GetType(Val.Value), False) Then
                                    If _functionSignature.Parameters(_counter).Type.IsNot("_functionSignature.Parameters(_counter).Type", _parameters(_counter).GetType(), "_parameters(_counter).GetType()", False) Then
                                        _returnValue = False
                                    End If
                                Else
                                    If _parameters(_counter).IsOfType("_parameters(_counter)", GetType(Variable), False) Then
                                        If CType(_parameters(_counter), Variable).Type.IsNull("CType(_parameters(_counter),Variable).Type", False) Then
                                            _returnValue = False
                                        Else
                                            If _functionSignature.Parameters(_counter).Type.IsNot("_functionSignature.Parameters(_counter).Type", CType(_parameters(_counter), Variable).Type, "CType(_parameters(_counter), Variable).Type", False) Then
                                                _returnValue = False
                                            End If
                                        End If
                                    Else
                                        If _parameters(_counter).IsOfType("_parameters(_counter)", GetType(FunctionCall), False) Then
                                            If _functionSignature.Parameters(_counter).Type.IsNot("_functionSignature.Parameters(_counter).Type", CType(_parameters(_counter), FunctionCall).FunctionSignature.Result.Type, "CType(_parameters(_counter), FunctionCall).FunctionSignature.Result.Type", False) Then
                                                _returnValue = False
                                            End If
                                        Else
                                            _returnValue = False
                                        End If
                                    End If
                                End If
                                If _returnValue.IsTrueNot("_returnValue", False) Then
                                    Exit For
                                End If
                            Next _counter
                        End If
                    End If
                End If
            End If

            Return _returnValue
        End Function

    End Class
End Namespace
